package com.lnj.orders.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lnj.api.IdGeneratorApi;
import com.lnj.bean.model.Address;
import com.lnj.orders.mapper.AddressMapper;
import com.lnj.orders.service.AddressService;
import com.lnj.utils.ResponseResult;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;

/**
 * 用户收货地址 Service 实现类
 */
@Service
@CacheConfig(cacheNames = "addresses") // 指定缓存名称
public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> implements AddressService {

    // 状态常量
    private static final int ADDRESS_STATUS_NORMAL = 1; // 正常状态
    private static final int ADDRESS_STATUS_DELETED = 0; // 已删除状态
    private static final int IS_DEFAULT = 1; // 默认地址
    private static final int NOT_DEFAULT = 0; // 非默认地址

    @Autowired
    private IdGeneratorApi idGeneratorApi;

    /**
     * 根据用户ID查询所有有效地址，并进行缓存
     *
     * @param userId 用户ID
     * @return 地址列表
     */
    @Override
    @Cacheable(value = "addresses", key = "#userId")
    public List<Address> listByUserId(@Param("userId") Long userId) {
        LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Address::getUserId, userId);
        wrapper.eq(Address::getAddressStatus, ADDRESS_STATUS_NORMAL);
        wrapper.orderByDesc(Address::getIsDefault); // 默认地址优先
        return this.list(wrapper);
    }

    /**
     * 添加新地址
     *
     * @param address 地址实体
     */
    @Override
    @Transactional
    @CacheEvict(key = "#address.userId") // 添加新地址后清除该用户的地址缓存
    public void addNewAddress(Address address) {
        if (address.getIsDefault().equals(IS_DEFAULT)) {
            // 如果新地址设置为默认，则清除该用户其他默认地址
            this.baseMapper.clearDefaultStatus(address.getUserId());
        }
        ResponseResult rr = this.idGeneratorApi.getNextId();
        if (rr.getCode() != 1) {
            throw new RuntimeException("地址ID生成失败");
        }
        Long addressId = Long.parseLong(rr.getData().toString());
        address.setAddressId(addressId);
        address.setAddressStatus(ADDRESS_STATUS_NORMAL);
        this.save(address);
    }

    /**
     * 更新地址信息
     *
     * @param address 地址实体
     */
    @Override
    @Transactional
    @CacheEvict(key = "#address.userId") // 更新地址后清除该用户的地址缓存
    public void updateAddressInfo(Address address) {
        Assert.notNull(address.getAddressId(), "地址ID不能为空");
        if (address.getIsDefault().equals(IS_DEFAULT)) {
            // 如果更新后设置为默认，则清除该用户其他默认地址
            this.baseMapper.clearDefaultStatus(address.getUserId());
        }
        this.updateById(address);
    }

    /**
     * 软删除地址
     *
     * @param addressId 地址ID
     */
    @Override
    @Transactional
    @CacheEvict(allEntries = true) // 软删除操作比较特殊，直接清空所有地址缓存以确保数据一致性
    public void softDeleteAddress(Long addressId) {
        Assert.notNull(addressId, "地址ID不能为空");
        Address address = new Address();
        address.setAddressId(addressId);
        address.setAddressStatus(ADDRESS_STATUS_DELETED);
        this.updateById(address);
    }

    /**
     * 设置某个地址为默认地址
     *
     * @param userId 用户ID
     * @param addressId 地址ID
     */
    @Override
    @Transactional
    @CacheEvict(key = "#userId") // 设置默认地址后清除该用户的地址缓存
    public void setDefaultAddress(@Param("userId") Long userId, @Param("addressId") Long  addressId) {
        Assert.notNull(userId, "用户ID不能为空");
        Assert.notNull(addressId, "地址ID不能为空");

        // 1. 清除该用户所有地址的默认状态
        this.baseMapper.clearDefaultStatus(userId);

        // 2. 将指定地址设置为默认
        Address address = new Address();
        address.setAddressId(addressId);
        address.setIsDefault(IS_DEFAULT);
        this.updateById(address);
    }
}

